//==========================================================================
// Copyright (c) 2000-2006,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include "display_def.h"
#include <util.h>
#include <bulverde.h>
static void LcdParamInit(DisplayContext *pCxt)
{
    pCxt->basePlaneFormat = BASEPLANE_COLORFORMAT;
    pCxt->vaBasePlane = NULL;
    pCxt->overlay[1].Enable = FALSE;
    pCxt->overlay[2].Enable = FALSE;
}

static void SetDisplayDesc(DisplayContext *pCxt)
{
    // Alloc Buffer for all channel DMA descriptors, 1 page OK.
    pCxt->vaChan0Desc = (UINT)Drv_AllocBuffer(1, DRVBUF_SPEED_FAST);
    pCxt->paChan0Desc =
        Drv_GetBufferPhysicalAddress((void *)pCxt->vaChan0Desc);

    pCxt->vaChan1Desc = pCxt->vaChan0Desc  + DESC_SIZE;
    pCxt->vaChan2Desc = pCxt->vaChan1Desc  + DESC_SIZE;
    pCxt->vaChan3Desc = pCxt->vaChan2Desc  + DESC_SIZE;
    pCxt->vaChan4Desc = pCxt->vaChan3Desc  + DESC_SIZE;
    pCxt->vaChan1AltDesc = pCxt->vaChan4Desc + DESC_SIZE;
    pCxt->vaPaletteDesc = pCxt->vaChan1AltDesc + DESC_SIZE;

    pCxt->paChan1Desc = pCxt->paChan0Desc  + DESC_SIZE;
    pCxt->paChan2Desc = pCxt->paChan1Desc  + DESC_SIZE;
    pCxt->paChan3Desc = pCxt->paChan2Desc  + DESC_SIZE;
    pCxt->paChan4Desc = pCxt->paChan3Desc  + DESC_SIZE;
    pCxt->paChan1AltDesc = pCxt->paChan4Desc + DESC_SIZE;
    pCxt->paPaletteDesc = pCxt->paChan1AltDesc + DESC_SIZE;
}

static BOOL SetBaseplaneBuffer(DisplayContext *pCxt, UINT flag)
{
    // Alloc Buffer for baseplane framebuffer
    pCxt->vaBasePlane =
        (unsigned int)Drv_ReallocBuffer(
        (void *)pCxt->vaBasePlane,
        BASEPLANE_FB_PAGES, BASEPLANE_FB_PAGES, flag);
    if (!pCxt->vaBasePlane) {
        printk("Alloc baseplane buffer error!\n");
        return FALSE;
    }

    pCxt->paBasePlane =
        Drv_GetBufferPhysicalAddress((void *)pCxt->vaBasePlane);

    return TRUE;
}

static void ClearBaseplane(DisplayContext *pCxt)
{
    memset((void *)pCxt->vaBasePlane, 0x0, 240*320*2);
}

void *Display_GetBasePlane(DisplayContext *pCxt)
{
    return (void *)pCxt->vaBasePlane;
}

ECODE Display_Create(DisplayContext *pCxt)
{
    SetDisplayDesc(pCxt);
    LcdParamInit(pCxt);
    if (!SetBaseplaneBuffer(pCxt, DRVBUF_SPEED_FAST)) return E_ACCESS_DENIED;
    return NOERROR;
}

void BackLight_Open(DisplayContext *pCxt);

ECODE Display_Init(DisplayContext *pCxt)
{
    // Before init, disable LCD controller
    LcdCtrl_Disable(pCxt);
    // Initialize the GPIO registers for proper LCD Controller operation
    Lcm_SetupGPIOs(pCxt);
    // Open back light
    //BackLight_Open(pCxt);
    Lcm_DisplayOn(pCxt);
    // Initialize the LCD Controller and frame descriptors
    LcdCtrl_Init(pCxt);
    // Enable the LCD controller
    LcdCtrl_Enable(pCxt);
    //BackLight_Open();

    ClearBaseplane(pCxt);
    return NOERROR;
}

// Special use
ECODE Display_ChangeBasePlaneFormat(DisplayContext *pCxt, ColorFormat format)
{
    if (pCxt->basePlaneFormat == COLOR_RGB565) {
        if (format == COLOR_RGBT555) {
            pCxt->basePlaneFormat = COLOR_RGBT555;
            goto CanSet;
        }
    }
    else if (pCxt->basePlaneFormat == COLOR_RGBT555) {
        if (format == COLOR_RGB565) {
            pCxt->basePlaneFormat = COLOR_RGB565;
            goto CanSet;
        }
    }

// CannotSet:
    return E_ACCESS_DENIED;

CanSet:
    LcdCtrl_Disable(pCxt);
    LcdCtrl_Init(pCxt);
    LcdCtrl_Enable(pCxt);
    return NOERROR;

}
static DisplayContext m_disCxt;
void Xs_LCD_Init()
{
    Drv_InitBuffer();
    Display_Create(&m_disCxt);
    Display_Init(&m_disCxt);
}

int ReadLogo(int ptr, int size);
void msleep(unsigned int ms);

extern int onkeyPressed;
void Display_Logo()
{
    ReadLogo((int)m_disCxt.paBasePlane, 240*320*2);
    if(!onkeyPressed) {
        msleep(150);//Wait for lcm init ok
        BackLight_Open(&m_disCxt);
    }
}

void backlight_open()
{
    BackLight_Open(&m_disCxt);
}

int Do_InitLcd(void)
{
    static BOOL bInitLcd = FALSE;
    if (!bInitLcd) {
        Xs_LCD_Init();
        bInitLcd = TRUE;
    }
    printk("\nm_disCxt.paBasePlane= %x\n", m_disCxt.paBasePlane);
    return 0;
}

int Do_ShowLogo(char *param)
{
    Do_InitLcd();//LNOTENOTE: Move to MainInitTbl later
    Display_Logo();
    return 0;
}

void write_data_disCxt(int offset, int size, unsigned short data)
{
    unsigned short *pFrame= (unsigned short *)m_disCxt.paBasePlane;
    if (NULL == pFrame) return ;
    pFrame += offset;

    int i;
    for (i=0; i < size; i++) {
        pFrame[i] = data;
    }
    return ;
}

unsigned int GetBasePlaneBufAddr(void)
{
	return m_disCxt.paBasePlane;
}
